import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'

// 创建自定义接口扩展AxiosRequestConfig
interface RequestOptions extends AxiosRequestConfig {
  // 是否显示loading
  showLoading?: boolean
  // 是否显示错误信息
  showError?: boolean
  // 重试次数
  retryCount?: number
  // 重试延迟时间(毫秒)
  retryDelay?: number
}

// 响应数据接口
interface ResponseData<T = any> {
  code: number
  data: T
  message: string
}
let baseURL = import.meta.env.MODE === 'development'?'/api':import.meta.env.VITE_API_BASE_URL

// 创建axios实例
const service: AxiosInstance = axios.create({
  baseURL , // 接口基础路径
  timeout: 10000, // 请求超时时间
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  }
})

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 在请求发送前做些什么
    
    // 获取token，可以从pinia或localStorage获取
    const token = localStorage.getItem('token')
    
    // 如果有token，则添加到请求头中
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`
    }
    
    return config
  },
  (error) => {
    // 处理请求错误
    console.error('请求错误：', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    const res = response.data as ResponseData
    
    // 根据自定义状态码判断请求是否成功
    // if (res.code !== 200) {
    //   // 处理业务错误
    //   handleError(res)
      
    //   // 根据不同的错误码进行不同的操作
    //   if (res.code === 401) {
    //     // 401: 未登录或token过期
    //     // 可以在这里执行退出登录操作
    //     localStorage.removeItem('token')
    //     // 可以使用router进行跳转到登录页
    //     window.location.href = '/login'
    //   }
      
    //   return Promise.reject(new Error(res.message || '未知错误'))
    // }
    
    // 返回原始响应，保留axios响应格式
    return response
  },
  (error: AxiosError) => {
    // 处理响应错误
    handleNetworkError(error)
    return Promise.reject(error)
  }
)

// 处理业务错误
function handleError(res: ResponseData) {
  // 可以使用element-plus等UI库显示错误消息
  console.error(`错误: ${res.message}`, res.code)
}

// 处理网络错误
function handleNetworkError(error: AxiosError) {
  let message = '未知错误'
  if (error.response) {
    // 请求成功发出且服务器也响应了状态码，但状态码超出了2xx的范围
    const status = error.response.status
    switch (status) {
      case 400:
        message = '请求错误'
        break
      case 401:
        message = '未授权，请重新登录'
        break
      case 403:
        message = '拒绝访问'
        break
      case 404:
        message = '请求地址出错'
        break
      case 408:
        message = '请求超时'
        break
      case 500:
        message = '服务器内部错误'
        break
      case 501:
        message = '服务未实现'
        break
      case 502:
        message = '网关错误'
        break
      case 503:
        message = '服务不可用'
        break
      case 504:
        message = '网关超时'
        break
      case 505:
        message = 'HTTP版本不受支持'
        break
      default:
        message = `未知错误(${status})`
    }
  } else if (error.request) {
    // 请求已经成功发起，但没有收到响应
    message = '网络异常，请检查您的网络连接'
  } else {
    // 发送请求时出了点问题
    message = `请求错误: ${error.message}`
  }
  
  console.error(`网络错误: ${message}`)
}

// 创建请求方法类型
type RequestMethod<T = any> = (url: string, data?: any, options?: RequestOptions) => Promise<T>

// 创建请求函数
const request = {
  // GET请求
  get<T = any>(url: string, params?: any, options?: RequestOptions): Promise<ResponseData<T>> {
    return service.get(url, { params, ...options }).then(res => res.data)
  },
  
  // POST请求
  post<T = any>(url: string, data?: any, options?: RequestOptions): Promise<ResponseData<T>> {
    return service.post(url, data, options).then(res => res.data)
  },
  
  // PUT请求
  put<T = any>(url: string, data?: any, options?: RequestOptions): Promise<ResponseData<T>> {
    return service.put(url, data, options).then(res => res.data)
  },
  
  // DELETE请求
  delete<T = any>(url: string, params?: any, options?: RequestOptions): Promise<ResponseData<T>> {
    return service.delete(url, { params, ...options }).then(res => res.data)
  },
  
  // 自定义请求
  request<T = any>(config: RequestOptions): Promise<ResponseData<T>> {
    return service(config).then(res => res.data)
  }
}

// 导出请求实例和请求方法
export default request
